package com.rem.concurrency.juc.my14Cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author Rem
 * @date 2021-03-11
 */

public class CasDemo2 {


    /**
     * CAS compareAndSet : 比较并交换！
     * 正常在业务操作，这里面比较的都是一个个对象
     * AtomicStampedReference 注意，如果泛型是一个包装类，注意对象的引用问题
     * <p>
     * Integer 使用了对象缓存机制，默认范围是 -128 ~ 127 ，推荐使用静态工厂方法 valueOf 获取对象实
     * 例，而不是 new，因为 valueOf 使用缓存，而 new 一定会创建新的对象分配新的内存空间；
     */
    private static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1, 1);

    public static void main(String[] args) {

        new Thread(() -> {
            // 获得版本号
            int stamp = atomicStampedReference.getStamp();
            System.out.println("a1=>" + stamp);

            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            atomicStampedReference.compareAndSet(1, 2, stamp, stamp + 1);

            stamp = atomicStampedReference.getStamp();
            System.out.println("a2=>" + stamp);
            System.out.println(atomicStampedReference.compareAndSet(2, 1, stamp, stamp + 1));
            System.out.println("a3=>" + atomicStampedReference.getStamp());

        }, "a").start();

        // 乐观锁的原理相同！
        new Thread(() -> {
            // 获得版本号
            int stamp = atomicStampedReference.getStamp();
            System.out.println("b1=>" + stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicStampedReference.compareAndSet(1, 6, stamp, stamp + 1));
            System.out.println("b2=>" + atomicStampedReference.getStamp());

        }, "b").start();
    }
}
